#ifndef _HELIX_ODE_PHYSICS_H_
#define _HELIX_ODE_PHYSICS_H_

#include "../../Helix.h"
#include "../../HObject.h"
#include "../../Log.h"
#include "../../Math/HelixMath.h"
#include <ode/ode.h>
#include "Physics.h"
#include "PhysObject.h"
#include "PhysObjRepresentation.h"


namespace helix
{
	/** This is an interface for a physics engine.
	*/
	class MY_CLASS ODEPhysics : public Physics
	{
	private:
		dWorldID world;
		dSpaceID space;
		dJointGroupID contactgroup;

		//The callback function to handle collisions 
		static void CollisionCallback (void *pData, dGeomID o1, dGeomID o2);

		static const int MAX_CONTACTS = 32;
		static const int NUM_ITERATIONS = 20;

	public:

		/** Create the physics simulation object.  
		*	\see Physics::Physics
		*/
		ODEPhysics(Vector minWorldExtents, Vector maxWorldExtents);

		~ODEPhysics();

		/** Create a PhysObject from the supplied PhysObjRepresentation object
		*	\see Physics::createPhysObject
		*/
		PhysObject *createPhysObject(PhysRepresentation *rep,bool isStatic);

		/** Delete the specified PhysObject instance, freeing it from the physics simulation  
		*	\see Physics::deletePhysObject
		*/
		void deletePhysObject(PhysObject *physObj);

		/** Updates the physics simulation.  Performs collision detection and physically simulates
		*	all physics objects.
		*	\see Physics::update
		*/
		void update(double dTime);

		/** \return Get the dWorldId of the physics simulation (this is specific to ODE)  
		*/
		dWorldID getWorldId()
		{
			return world;
		}

		/** \return Get the dSpaceId of the physics simulation (this is specific to ODE)  
		*/
		dSpaceID getSpaceId(){
			return space;
		}

		/** \return Get the dContactGroupID of the physics simulation (this is specific to ODE)  
		*/
		dJointGroupID getContactGroupId(){
			return contactgroup;
		}
	};

}

#endif